// c07_integer_comparison - 整数比较：大小比较与相等判断
// 深入学习Rust中整数比较操作的各种用法、注意事项和最佳实践

fn main() {
    println!("=== Rust 整数比较操作示例 ===\n");
    
    // 1. 基本比较操作符
    demonstrate_basic_comparison_operators();
    
    // 2. 相等性判断详解
    demonstrate_equality_comparisons();
    
    // 3. 大小比较详解  
    demonstrate_ordering_comparisons();
    
    // 4. 不同类型间的比较
    demonstrate_cross_type_comparisons();
    
    // 5. 边界值比较
    demonstrate_boundary_comparisons();
    
    // 6. 比较操作的链式调用
    demonstrate_chained_comparisons();
    
    // 7. 实际应用场景
    demonstrate_real_world_applications();
    
    // 8. 性能考虑和最佳实践
    demonstrate_performance_and_best_practices();
    
    println!("\n=== 总结 ===");
    println!("✓ 掌握了6个基本比较操作符的使用");
    println!("✓ 理解了不同类型间比较的注意事项");
    println!("✓ 学会了在实际场景中应用整数比较");
    println!("✓ 了解了比较操作的性能特点和最佳实践");
    println!("整数比较是编程中最基础也是最重要的操作之一！");
}

/// 演示基本比较操作符
fn demonstrate_basic_comparison_operators() {
    println!("1. 基本比较操作符");
    println!("   Rust 提供 6 个比较操作符：== != < <= > >=");
    
    let a = 10i32;
    let b = 20i32;
    let c = 10i32;
    
    println!("\n1.1 使用示例 (a = {}, b = {}, c = {})", a, b, c);
    
    // 相等性比较
    println!("相等性比较：");
    println!("  a == c: {} (10 等于 10)", a == c);
    println!("  a == b: {} (10 不等于 20)", a == b);
    println!("  a != b: {} (10 不等于 20)", a != b);
    println!("  a != c: {} (10 等于 10)", a != c);
    
    // 大小比较
    println!("\n大小比较：");
    println!("  a < b:  {} (10 小于 20)", a < b);
    println!("  a <= c: {} (10 小于等于 10)", a <= c);
    println!("  b > a:  {} (20 大于 10)", b > a);
    println!("  c >= a: {} (10 大于等于 10)", c >= a);
    
    // 比较结果的类型
    println!("\n1.2 比较操作返回 bool 类型");
    let is_equal = a == c;
    let is_greater = b > a;
    println!("  is_equal 的类型是 bool: {}", is_equal);
    println!("  is_greater 的类型是 bool: {}", is_greater);
    
    // 比较操作的优先级
    println!("\n1.3 比较操作符的优先级");
    let result1 = 5 + 3 > 2 * 3;  // (5 + 3) > (2 * 3) = 8 > 6 = true
    let result2 = 10 - 5 == 2 + 3;  // (10 - 5) == (2 + 3) = 5 == 5 = true
    println!("  5 + 3 > 2 * 3 = {} (先算术后比较)", result1);
    println!("  10 - 5 == 2 + 3 = {} (先算术后比较)", result2);
    
    println!("==================================================\n");
}

/// 演示相等性判断详解
fn demonstrate_equality_comparisons() {
    println!("2. 相等性判断详解");
    println!("   == 和 != 操作符用于判断两个值是否相等");
    
    println!("\n2.1 基本相等性判断");
    let x = 42;
    let y = 42;
    let z = 43;
    
    println!("  {} == {} = {}", x, y, x == y);
    println!("  {} == {} = {}", x, z, x == z);
    println!("  {} != {} = {}", x, z, x != z);
    
    // 零值比较
    println!("\n2.2 零值比较");
    let zero_i32 = 0i32;
    let zero_u32 = 0u32;
    let negative = -1i32;
    
    println!("  0i32 == 0: {}", zero_i32 == 0);
    println!("  0u32 == 0: {}", zero_u32 == 0);
    println!("  -1 == 0: {}", negative == 0);
    println!("  -1 != 0: {}", negative != 0);
    
    // 相等性的对称性
    println!("\n2.3 相等性的数学性质");
    let p = 15;
    let q = 15;
    let r = 15;
    
    println!("  对称性: {} == {} 等于 {} == {} = {}", p, q, q, p, (p == q) == (q == p));
    println!("  传递性: 如果 {} == {} 且 {} == {}，那么 {} == {} = {}", 
             p, q, q, r, p, r, (p == q && q == r) == (p == r));
    println!("  反身性: {} == {} = {}", p, p, p == p);
    
    // 边界情况
    println!("\n2.4 边界值的相等性比较");
    let max_u8 = u8::MAX;
    let also_max_u8 = 255u8;
    let min_i8 = i8::MIN;
    let also_min_i8 = -128i8;
    
    println!("  u8::MAX == 255u8: {}", max_u8 == also_max_u8);
    println!("  i8::MIN == -128i8: {}", min_i8 == also_min_i8);
    
    println!("==================================================\n");
}

/// 演示大小比较详解
fn demonstrate_ordering_comparisons() {
    println!("3. 大小比较详解");
    println!("   <, <=, >, >= 操作符用于比较数值的大小关系");
    
    println!("\n3.1 基本大小比较");
    let small = 5;
    let medium = 15;
    let large = 25;
    
    println!("  {} < {} = {}", small, medium, small < medium);
    println!("  {} <= {} = {}", small, small, small <= small);
    println!("  {} > {} = {}", large, medium, large > medium);
    println!("  {} >= {} = {}", medium, medium, medium >= medium);
    
    // 大小比较的传递性
    println!("\n3.2 大小比较的数学性质");
    println!("  传递性: 如果 {} < {} 且 {} < {}，那么 {} < {} = {}", 
             small, medium, medium, large, small, large, 
             (small < medium && medium < large) == (small < large));
    println!("  反对称性: {} < {} 与 {} < {} 不能同时为真", small, medium, medium, small);
    println!("    {} < {} = {}, {} < {} = {}", 
             small, medium, small < medium, medium, small, medium < small);
    
    // 负数比较
    println!("\n3.3 有符号整数的比较（包括负数）");
    let negative_large = -50i32;
    let negative_small = -10i32;
    let positive = 5i32;
    
    println!("  {} < {} = {} (较大的负数小于较小的负数)", negative_large, negative_small, negative_large < negative_small);
    println!("  {} < {} = {} (负数小于正数)", negative_small, positive, negative_small < positive);
    println!("  {} > {} = {} (正数大于负数)", positive, negative_large, positive > negative_large);
    
    // 比较操作符的组合使用
    println!("\n3.4 比较操作符的组合使用");
    let value = 10;
    let min_range = 5;
    let max_range = 15;
    
    let in_range = value >= min_range && value <= max_range;
    let out_of_range = value < min_range || value > max_range;
    
    println!("  检查 {} 是否在 [{}, {}] 范围内: {}", value, min_range, max_range, in_range);
    println!("  检查 {} 是否在 [{}, {}] 范围外: {}", value, min_range, max_range, out_of_range);
    
    println!("==================================================\n");
}

/// 演示不同类型间的比较
fn demonstrate_cross_type_comparisons() {
    println!("4. 不同类型间的比较");
    println!("   Rust 要求比较操作的两个操作数必须是相同类型");
    
    println!("\n4.1 相同类型的比较（正常情况）");
    let a_i32 = 10i32;
    let b_i32 = 20i32;
    let c_u32 = 15u32;
    let d_u32 = 25u32;
    
    println!("  i32 比较: {} < {} = {}", a_i32, b_i32, a_i32 < b_i32);
    println!("  u32 比较: {} < {} = {}", c_u32, d_u32, c_u32 < d_u32);
    
    println!("\n4.2 类型转换后的比较");
    println!("  需要显式转换才能比较不同类型：");
    
    let i32_val = 10i32;
    let u32_val = 15u32;
    
    // 演示类型转换比较
    println!("  {} (i32) vs {} (u32):", i32_val, u32_val);
    println!("    转换为相同类型比较: {} < {} = {}", 
             i32_val, u32_val as i32, i32_val < (u32_val as i32));
    println!("    或者: {} < {} = {}", 
             i32_val as u32, u32_val, (i32_val as u32) < u32_val);
    
    // 有符号和无符号数比较的注意事项
    println!("\n4.3 有符号和无符号数比较的陷阱");
    let signed_negative = -1i32;
    let unsigned_small = 1u32;
    
    println!("  注意：直接转换可能产生意外结果");
    println!("  {} (i32) 转换为 u32: {}", signed_negative, signed_negative as u32);
    println!("  比较结果: {} as u32 > {} = {}", 
             signed_negative, unsigned_small, (signed_negative as u32) > unsigned_small);
    
    // 安全的跨类型比较方法
    println!("\n4.4 安全的跨类型比较方法");
    
    fn safe_compare_i32_u32(signed: i32, unsigned: u32) -> std::cmp::Ordering {
        if signed < 0 {
            std::cmp::Ordering::Less  // 负数总是小于无符号数
        } else {
            (signed as u32).cmp(&unsigned)
        }
    }
    
    let result = safe_compare_i32_u32(-5, 3);
    println!("  安全比较 -5 (i32) 与 3 (u32): {:?}", result);
    
    let result2 = safe_compare_i32_u32(10, 3);
    println!("  安全比较 10 (i32) 与 3 (u32): {:?}", result2);
    
    println!("==================================================\n");
}

/// 演示边界值比较
fn demonstrate_boundary_comparisons() {
    println!("5. 边界值比较");
    println!("   在处理类型边界值时需要特别注意");
    
    println!("\n5.1 各类型的边界值");
    println!("  u8:  MIN = {}, MAX = {}", u8::MIN, u8::MAX);
    println!("  i8:  MIN = {}, MAX = {}", i8::MIN, i8::MAX);
    println!("  u16: MIN = {}, MAX = {}", u16::MIN, u16::MAX);
    println!("  i16: MIN = {}, MAX = {}", i16::MIN, i16::MAX);
    println!("  u32: MIN = {}, MAX = {}", u32::MIN, u32::MAX);
    println!("  i32: MIN = {}, MAX = {}", i32::MIN, i32::MAX);
    
    println!("\n5.2 边界值的比较操作");
    
    // 最大值和最小值的比较
    println!("  边界值间的比较：");
    println!("    u8::MAX > u8::MIN: {}", u8::MAX > u8::MIN);
    println!("    i8::MAX > i8::MIN: {}", i8::MAX > i8::MIN);
    println!("    i8::MIN < 0: {}", i8::MIN < 0);
    println!("    u8::MIN == 0: {}", u8::MIN == 0);
    
    // 临近边界值的比较
    println!("\n5.3 临近边界值的比较");
    let near_max_u8 = u8::MAX - 1;  // 254
    let near_min_i8 = i8::MIN + 1;  // -127
    
    println!("  接近边界的值：");
    println!("    {} < u8::MAX: {}", near_max_u8, near_max_u8 < u8::MAX);
    println!("    {} > i8::MIN: {}", near_min_i8, near_min_i8 > i8::MIN);
    
    // 边界值在实际应用中的比较
    println!("\n5.4 边界值比较的实际应用");
    
    fn check_u8_range(value: i32) -> &'static str {
        if value < u8::MIN as i32 {
            "小于 u8 最小值"
        } else if value > u8::MAX as i32 {
            "大于 u8 最大值"
        } else {
            "在 u8 范围内"
        }
    }
    
    let test_values = [-10i32, 100i32, 300i32];
    for &val in &test_values {
        println!("    {} 的范围检查: {}", val, check_u8_range(val));
    }
    
    // 溢出前的比较
    println!("\n5.5 防溢出的比较操作");
    let large_u8 = 200u8;
    let addition_amount = 100u8;
    
    // 检查加法是否会溢出
    let would_overflow = large_u8 > u8::MAX - addition_amount;
    println!("  {} + {} 会导致溢出吗？{}", large_u8, addition_amount, would_overflow);
    
    if would_overflow {
        println!("    使用饱和加法: {} + {} = {}", 
                large_u8, addition_amount, large_u8.saturating_add(addition_amount));
    } else {
        println!("    安全加法: {} + {} = {}", 
                large_u8, addition_amount, large_u8 + addition_amount);
    }
    
    println!("==================================================\n");
}

/// 演示比较操作的链式调用
fn demonstrate_chained_comparisons() {
    println!("6. 比较操作的链式调用");
    println!("   在Rust中不能直接链式比较，但可以通过逻辑操作符组合");
    
    println!("\n6.1 不能直接链式比较");
    println!("  Python: 1 < 2 < 3  ✓");
    println!("  Rust:   1 < 2 < 3  ✗ (编译错误)");
    println!("  原因：比较结果是 bool 类型，bool 不能与数字比较");
    
    println!("\n6.2 正确的多重比较方法");
    let a = 1;
    let b = 2; 
    let c = 3;
    
    // 使用逻辑与操作符
    let ascending = a < b && b < c;
    println!("  检查递增: {} < {} && {} < {} = {}", a, b, b, c, ascending);
    
    let descending = a > b && b > c;
    println!("  检查递减: {} > {} && {} > {} = {}", a, b, b, c, descending);
    
    // 范围检查
    let value = 15;
    let min_val = 10;
    let max_val = 20;
    
    let in_range = min_val <= value && value <= max_val;
    println!("  范围检查: {} <= {} <= {} = {}", min_val, value, max_val, in_range);
    
    // 使用范围模式匹配
    println!("\n6.3 使用 match 进行范围比较");
    
    fn describe_number(n: i32) -> &'static str {
        match n {
            n if n < 0 => "负数",
            0 => "零",
            1..=10 => "小正数",
            11..=100 => "中等正数", 
            _ => "大正数"
        }
    }
    
    let test_numbers = [-5, 0, 5, 50, 500];
    for &num in &test_numbers {
        println!("    {} 是 {}", num, describe_number(num));
    }
    
    // 使用 matches! 宏
    println!("\n6.4 使用 matches! 宏进行模式比较");
    for &num in &test_numbers {
        let is_positive_small = matches!(num, 1..=10);
        println!("    {} 是小正数吗？{}", num, is_positive_small);
    }
    
    println!("==================================================\n");
}

/// 演示实际应用场景
fn demonstrate_real_world_applications() {
    println!("7. 实际应用场景");
    
    println!("\n7.1 排序算法中的比较");
    let mut numbers = vec![64, 34, 25, 12, 22, 11, 90];
    println!("  原始数组: {:?}", numbers);
    
    // 冒泡排序示例
    bubble_sort(&mut numbers);
    println!("  排序后: {:?}", numbers);
    
    println!("\n7.2 查找算法中的比较");
    let sorted_array = [1, 3, 5, 7, 9, 11, 13, 15];
    let target = 7;
    
    match binary_search(&sorted_array, target) {
        Some(index) => println!("  在已排序数组中找到 {} at index {}", target, index),
        None => println!("  在已排序数组中未找到 {}", target),
    }
    
    println!("\n7.3 数值分类和筛选");
    let numbers = vec![1, -3, 5, -7, 9, -2, 4, 8];
    
    let positives: Vec<i32> = numbers.iter().filter(|&&x| x > 0).cloned().collect();
    let negatives: Vec<i32> = numbers.iter().filter(|&&x| x < 0).cloned().collect();
    let zeros: Vec<i32> = numbers.iter().filter(|&&x| x == 0).cloned().collect();
    
    println!("  原始数组: {:?}", numbers);
    println!("  正数: {:?}", positives);
    println!("  负数: {:?}", negatives);
    println!("  零: {:?}", zeros);
    
    println!("\n7.4 边界检查和验证");
    
    // 年龄验证示例
    fn validate_age(age: i32) -> Result<u8, String> {
        if age < 0 {
            Err("年龄不能为负数".to_string())
        } else if age > 150 {
            Err("年龄不能超过150岁".to_string())
        } else {
            Ok(age as u8)
        }
    }
    
    let test_ages = [-5, 25, 200];
    for &age in &test_ages {
        match validate_age(age) {
            Ok(valid_age) => println!("    年龄 {} 有效", valid_age),
            Err(error) => println!("    年龄 {} 无效: {}", age, error),
        }
    }
    
    println!("\n7.5 性能统计和比较");
    let scores = vec![85, 92, 78, 96, 88, 76, 94, 82];
    
    let min_score = scores.iter().min().unwrap();
    let max_score = scores.iter().max().unwrap();
    let passing_count = scores.iter().filter(|&&score| score >= 80).count();
    let excellent_count = scores.iter().filter(|&&score| score >= 90).count();
    
    println!("  成绩统计: {:?}", scores);
    println!("    最低分: {}", min_score);
    println!("    最高分: {}", max_score);
    println!("    及格人数 (>= 80): {}", passing_count);
    println!("    优秀人数 (>= 90): {}", excellent_count);
    
    println!("==================================================\n");
}

/// 演示性能考虑和最佳实践
fn demonstrate_performance_and_best_practices() {
    println!("8. 性能考虑和最佳实践");
    
    println!("\n8.1 比较操作的性能特点");
    println!("  基本比较操作是 O(1) 时间复杂度");
    println!("  整数比较通常是单个 CPU 指令");
    println!("  不同大小的整数类型比较性能基本相同");
    
    println!("\n8.2 避免不必要的类型转换");
    println!("  ✅ 使用相同类型比较：let a: i32 = 10; let b: i32 = 20; a < b");
    println!("  ❌ 避免频繁转换：let a: i32 = 10; let b: i64 = 20; (a as i64) < b");
    
    println!("\n8.3 利用短路求值优化");
    let expensive_computation = || {
        println!("      执行了昂贵的计算");
        42
    };
    
    let condition = false;
    println!("  演示短路求值：");
    let _result = condition && expensive_computation() > 0;
    println!("    第二个条件不会被执行，因为第一个已经是 false");
    
    println!("\n8.4 选择合适的数据类型");
    println!("  根据数值范围选择最小的适用类型：");
    println!("    0-255 的值使用 u8");
    println!("    -128 到 127 的值使用 i8"); 
    println!("    百万级数值使用 u32 或 i32");
    
    println!("\n8.5 比较操作的最佳实践");
    println!("  📏 一致性：在同一个函数/模块中使用一致的比较风格");
    println!("  📖 可读性：使用有意义的变量名，如 min_age, max_score");
    println!("  🔒 边界检查：总是检查边界条件和特殊值");
    println!("  ⚡ 性能：避免在循环中进行复杂的类型转换");
    
    // 实用的比较函数示例
    println!("\n8.6 实用的比较函数示例");
    
    // 夹持函数（clamp）
    fn clamp(value: i32, min: i32, max: i32) -> i32 {
        if value < min {
            min
        } else if value > max {
            max
        } else {
            value
        }
    }
    
    println!("  夹持函数示例：");
    println!("    clamp(15, 10, 20) = {}", clamp(15, 10, 20));
    println!("    clamp(5, 10, 20) = {}", clamp(5, 10, 20));
    println!("    clamp(25, 10, 20) = {}", clamp(25, 10, 20));
    
    // 范围检查函数
    fn in_range<T: PartialOrd>(value: T, min: T, max: T) -> bool {
        value >= min && value <= max
    }
    
    println!("\n  泛型范围检查函数：");
    println!("    in_range(15, 10, 20) = {}", in_range(15, 10, 20));
    println!("    in_range(5u8, 10u8, 20u8) = {}", in_range(5u8, 10u8, 20u8));
    
    println!("==================================================\n");
}

// 辅助函数：冒泡排序
fn bubble_sort(arr: &mut [i32]) {
    let n = arr.len();
    for i in 0..n {
        for j in 0..(n - 1 - i) {
            if arr[j] > arr[j + 1] {  // 比较操作是排序的核心
                arr.swap(j, j + 1);
            }
        }
    }
}

// 辅助函数：二分查找
fn binary_search(arr: &[i32], target: i32) -> Option<usize> {
    let mut left = 0;
    let mut right = arr.len();
    
    while left < right {
        let mid = left + (right - left) / 2;
        if arr[mid] == target {      // 相等性比较
            return Some(mid);
        } else if arr[mid] < target { // 大小比较
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    None
}
